package com.cnaaa.pay.controller;

import com.alipay.api.AlipayApiException;
import com.cnaaa.pay.bo.TradeQuery;
import com.cnaaa.pay.entity.Trade;
import com.cnaaa.pay.service.AlipayService;
import com.cnaaa.pay.service.TradeService;
import com.cnaaa.pay.util.RequestParamUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 2018/10/26 Create by 郭文梁
 * AlipayController
 * 支付宝数据访问控制器
 *
 * @author 郭文梁
 * @date 2018/10/26
 */
@RestController
@RequestMapping("/alipay")
@Slf4j
public class AlipayController {
    private final AlipayService alipayService;
    private final TradeService tradeService;

    @Autowired
    public AlipayController(AlipayService alipayService, TradeService tradeService) {
        this.alipayService = alipayService;
        this.tradeService = tradeService;
    }

    /**
     * 查询订单状态
     *
     * @param tradeNo    支付宝订单号（与订单号二选一）
     * @param outTradeNo 订单号（与支付宝订单号二选一）
     * @return json
     * @throws AlipayApiException exception
     */
    @GetMapping("/query")
    public String query(String tradeNo, String outTradeNo) throws AlipayApiException {
        return alipayService.query(new TradeQuery(tradeNo, outTradeNo));
    }

    @GetMapping("/close")
    public String close(String tradeNo, String outTradeNo) throws AlipayApiException {
        return alipayService.close(new TradeQuery(tradeNo, outTradeNo)).getBody();
    }


    @PostMapping("/notify")
    public String notifyCallback(HttpServletRequest request) {
        Map<String, String> params = RequestParamUtil.prettyWithoutCharset(request.getParameterMap());
        boolean result = tradeService.onAlipayNotify(params);
        if (result) {
            result = checkTradeStatus(params);
        }
        return result ? "success" : "fail";
    }


    @GetMapping(value = "/pay/{tradeId}", produces = "text/html;charset=utf-8")
    public String pay(@PathVariable("tradeId") String tradeId) throws AlipayApiException {
        Trade trade = tradeService.findById(tradeId);
        if (canBePaid(trade)) {
            //记录支付方式
            trade.setPayBy(Trade.ALIPAY);
            //修改交易状态
            trade.setStatus(Trade.ACTIVE);
            trade = tradeService.save(trade);
            return alipayService.pay(trade);
        } else {
            return "交易状态无效";
        }
    }

    /**
     * 检查交易是否允许支付
     * 只有当（交易存在 && 交易状态为创建或活动）时 交易才允许支付
     *
     * @param trade 交易
     * @return 是否可支付
     */
    private boolean canBePaid(Trade trade) {
        return trade != null && (trade.getStatus() == Trade.ACTIVE || trade.getStatus() == Trade.CREATE);
    }

    /**
     * 检查订单状态 （暂未检查， 认为交易全部有效）
     * 触发场景 当支付宝返回到ReturnUrl时触发，此时应该检查订单的状态
     * 当状态为Active时，说明支付宝未调用notifyUrl（或服务器未正常接收到Notify），此时认为交易存在异常
     * 当状态为PAYED时，说明支付宝已经正常调用了Notify，并且交易已经成功，此时返回true即可
     * 当状态为其他任何状态时，都视为恶意请求，返回false
     *
     * @param params 参数
     */
    private boolean checkTradeStatus(Map<String, String> params) {
        String tradeNo = params.get("");
        //TODO 检查订单状态
        return true;
    }
}
